package drds.plus.datasource.exception_sorter;


import java.sql.SQLException;

public class ExceptionSorterImpl implements ExceptionSorter {

    public boolean isFatalException(SQLException e) {
        int loopCount = 20; // 防止人为失误，当两个Throwable互为对方的initCause()时，造成死循环

        Throwable cause = e;
        while (cause != null) {
            if (cause instanceof SQLException) {
                SQLException sqlException = (SQLException) cause;
                if (isExceptionFatal0(sqlException)) {
                    return true;
                }
            }

            cause = cause.getCause();
            if (--loopCount < 0) {
                break;
            }
        }

        return false;
    }

    private boolean isExceptionFatal0(SQLException e) {
        String sqlState = e.getSQLState();
        if (sqlState != null && sqlState.startsWith("08")) {
            return true;
        }
        switch (e.getErrorCode()) {
            // Communications Errors
            case 1040: // ER_CON_COUNT_ERROR
            case 1042: // ER_BAD_HOST_ERROR
            case 1043: // ER_HANDSHAKE_ERROR
            case 1047: // ER_UNKNOWN_COM_ERROR
            case 1081: // ER_IPSOCK_ERROR
            case 1129: // ER_HOST_IS_BLOCKED
            case 1130: // ER_HOST_NOT_PRIVILEGED

                // Authentication Errors
            case 1045: // ER_ACCESS_DENIED_ERROR

                // Resource errors
            case 1004: // ER_CANT_CREATE_FILE
            case 1005: // ER_CANT_CREATE_TABLE
            case 1015: // ER_CANT_LOCK
            case 1021: // ER_DISK_FULL
            case 1041: // ER_OUT_OF_RESOURCES

                // Out-of-memory errors
            case 1037: // ER_OUTOFMEMORY
            case 1038: // ER_OUT_OF_SORTMEMORY

                return true;
        }

        final String error_text = e.getMessage();
        return "no datasource!".equals(error_text) || "no alive datasource".equals(error_text);
    }
}
